package lixp.redis.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.*;


/**
 * 继承CachingConfigurerSupport只是为了重写keyGenerator()——key的默认生成策略
 * 也可以不重写，不重写的话，默认key为传过来的参数
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    //jackson序列化
    @Bean
    public RedisSerializer<Object> jackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        return serializer;
    }

    /**
     * RedisTemplate对象默认使用jdkSerializer实现序列化
     * 如果value是对象的话，使用json序列化
     * 这样主要考虑到可以通过可视化工具更好的查看数据
    */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //set key serializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key的序列化采用StringRedisSerializer
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        //使用jackson序列化内容，设置默认的序列化方式为json
        template.setDefaultSerializer(jackson2JsonRedisSerializer());
//        template.setValueSerializer(jackson2JsonRedisSerializer());
//        template.setHashValueSerializer(jackson2JsonRedisSerializer());
        //配置连接工厂
        template.setConnectionFactory(lettuceConnectionFactory);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 如果value是字符串的话，依然使用string序列化
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(lettuceConnectionFactory);
        return template;
    }

    //自定义redis缓存管理器
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //设置CacheManager的值序列化方式为json序列化
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
                .fromSerializer(jsonSerializer);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(pair);
        //设置默认超过期时间是30秒
        //defaultCacheConfig.entryTtl(Duration.ofSeconds(30));
        //初始化RedisCacheManager
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

    //自定义生成的key，默认为传过来的参数，这个一般来说可以不用
//    @Bean
//    @Override
//    public KeyGenerator keyGenerator() {
//        return new KeyGenerator() {
//
//            @Override
//            public StringBuilder generate(Object target, Method method, Object... params) {
//
//                StringBuilder stringBuilder = new StringBuilder();
//                stringBuilder
//                        .append(target.hashCode() + "-")
//                        .append(method.getName() + "-")
//                        .append(Arrays.asList(params).toString());
//                System.err.println(stringBuilder);
//                return stringBuilder;
//            }
//        };
//    }

}
